package com.cli.springboot_rabbitmq.config;

import com.cli.springboot_rabbitmq.model.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.UUID;

/**
 * @Author xiongmin
 * @Description
 * @Date 2021/2/26 10:35
 * @Version 1.0
 **/
@Slf4j
@Service
public class RabbitMQService {

//    @Resource(name = "rabbitTemplateMessaging")
//    private RabbitTemplate rabbitTemplate;

    /**
     * 换成这个RabbitTemplate 之后，所有的消费者都要手动Ack消息确认被消费
     */
    @Resource(name = "rabbitTemplateInit")
    private RabbitTemplate rabbitTemplate;


    // 发送消息的后置处理器，MessagePostProcessor类的postProcessMessage方法得到的Message就是将参数Object内容转换成Message对象
    // 没有指定具体的Exchange就会使用默认的Exchange
    public void messageDeliver(String routineKey, Object o) {
        rabbitTemplate.convertAndSend(routineKey, o, message -> {
            System.out.println("-------处理前message-------------");
            System.out.println(message);
            // 设置message的一些头部信息
            message.getMessageProperties().setMessageId(UUID.randomUUID().toString());
            message.getMessageProperties().setCorrelationId(UUID.randomUUID().toString());
            return message;
        });
    }

    // 发送消息的后置处理器，MessagePostProcessor类的postProcessMessage方法得到的Message就是将参数Object内容转换成Message对象
    public void messageDeliver(String exchange, String routineKey, Object o) {
        rabbitTemplate.convertAndSend(exchange, routineKey, o, message -> {
            System.out.println("-------处理前message-------------");
            System.out.println(message);
            // 设置message的一些头部信息
            message.getMessageProperties().setMessageId(UUID.randomUUID().toString());
            message.getMessageProperties().setCorrelationId(UUID.randomUUID().toString());
            message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
            System.out.println("-------处理后message-------------");
            System.out.println(message);
            return message;
        },new CorrelationData(UUID.randomUUID().toString()));
    }

    // 发送消息的后置处理器，MessagePostProcessor类的postProcessMessage方法得到的Message就是将参数Object内容转换成Message对象
    public void messageDeliver(String exchange, String routineKey, User user) {
        rabbitTemplate.convertAndSend(exchange, routineKey, user, message -> {
            System.out.println("-------处理前message-------------");
            System.out.println(message);
            // 设置message的一些头部信息
            /**
             * 消息在消费时，先根据消息投中给的messageId找到对饮给的User, 在判断User的状态是否已经被消费过
             * 感觉这也是一种防止消息重复消费的方式，即使同一个消息投递多次，也你能防止消息重复消费
             */
            message.getMessageProperties().setMessageId(user.getName());
            message.getMessageProperties().setCorrelationId(UUID.randomUUID().toString());
            message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
            System.out.println("-------处理后message-------------");
            System.out.println(message);
            return message;
        },new CorrelationData(UUID.randomUUID().toString()));
    }
}
